﻿namespace SAD.DataCenter
{
    using System;
    using System.Linq;
    using SAD.Common.Models;
    using System.Collections.Generic;
    using SAD.Common.Enums;
    using SAD.Common.Contracts.ShowNode;

    public class InfoManagerService : SAD.Common.Contracts.DataCenter.IInfoManager
    {
        public Info_Data[] GetInfos(int showNodeID, int infoCategoryID, DateTime limitStartTime, int size)
        {
            return InfoManager.Instance.GetInfos(showNodeID, infoCategoryID, limitStartTime, size);
        }
    }

    public class InfoManager
    {
        #region Instance
        /// <summary>
        /// 类型单例
        /// </summary>
        public static InfoManager Instance
        {
            get
            {
                return m_Instance;
            }
        }
        private static InfoManager m_Instance = new InfoManager();
        #endregion

        public Info_Data[] GetInfos(int showNodeID, int infoCategoryID, DateTime limitStartTime, int size)
        {
            Info_Data[] result = null;

            if (limitStartTime < DateTime.Parse("1900-01-01 00:00:00"))
            {
                limitStartTime = DateTime.Parse("1900-01-01 00:00:00");
            }

            using (SAD_Modles ctx = new SAD_Modles())
            {
                if (infoCategoryID > 0)
                {
                    var r = from info in ctx.Info_Datas where info.ShowNodeID == showNodeID && info.ShowStatus == (byte)Info_ShowStatus.Yes && info.InfoCategoryID == infoCategoryID && info.AddTime > limitStartTime orderby info.AddTime descending select info;
                    result = r.Skip(0).Take(size).ToArray();
                }
                else
                {
                    var r = from info in ctx.Info_Datas where info.ShowNodeID == showNodeID && info.ShowStatus == (byte)Info_ShowStatus.Yes && info.AddTime > limitStartTime orderby info.AddTime descending select info;
                    result = r.Skip(0).Take(size).ToArray();
                }
            }

            return result;
        }

        public long SendInfo(int showNodeID, int categoryID, Info_ShowType showType, string showData, int sendUserID, Info_SourceType sourceType, string sourceInfo)
        {
            Info_MacVerifyStatus info_MacVerifyStatus = Info_MacVerifyStatus.NoCheck;
            Info_ManVerifyStatus info_ManVerifyStatus = Info_ManVerifyStatus.NoCheck;
            Info_ShowStatus info_ShowStatus = Info_ShowStatus.No;

            Info_Data info = new Info_Data();
            info.InfoCategoryID = categoryID;
            info.ShowType = (byte)showType;
            info.ShowNodeID = showNodeID;
            info.ShowData = showData;
            info.SendUserID = sendUserID;
            info.SourceType = (byte)sourceType;
            info.SourceInfo = sourceInfo;
            info.AddTime = DateTime.Now;
            info.MacVerifyStatus = (byte)info_MacVerifyStatus;
            info.ManVerifyStatus = (byte)info_ManVerifyStatus;
            info.ShowStatus = (byte)info_ShowStatus;

            //Info_Data info = Info_Data.CreateInfo_Data(0, categoryID, (byte)showType, showNodeID, showData, sendUserID, (byte)sourceType, sourceInfo, DateTime.Now, (byte)info_MacVerifyStatus, (byte)info_ManVerifyStatus, (byte)info_ShowStatus);

            return SendInfo(info);
        }

        public long SendInfo(Info_Data info)
        {
            string showData = info.ShowData;
            SAD.DataCenter.AntiAttack.FilterResult filterResult = SAD.DataCenter.AntiAttack.WordFilter.Instance.Filter(ref showData);
            info.ShowData = showData;
            switch (filterResult)
            {
                case SAD.DataCenter.AntiAttack.FilterResult.Pass:
                    info.MacVerifyStatus = (byte)Info_MacVerifyStatus.CheckSucceed;
                    info.ShowStatus = (byte)Info_ShowStatus.Yes;
                    break;
                case SAD.DataCenter.AntiAttack.FilterResult.RecordOnly:
                    info.MacVerifyStatus = (byte)Info_MacVerifyStatus.CheckFail_Info;
                    break;
                case SAD.DataCenter.AntiAttack.FilterResult.Replace:
                    info.MacVerifyStatus = (byte)Info_MacVerifyStatus.CheckFail_Warn;
                    break;
                case SAD.DataCenter.AntiAttack.FilterResult.Banned:
                    info.MacVerifyStatus = (byte)Info_MacVerifyStatus.CheckFail_Banned;
                    break;
                default:
                    info.MacVerifyStatus = (byte)Info_MacVerifyStatus.CheckFail_Banned;
                    break;
            }
   
            using (SAD_Modles ctx = new SAD_Modles())
            {
                ctx.AddToInfo_Datas(info);
                ctx.SaveChanges();
            }

            InfoStatusChangeNoitfy(info);
            return info.ID;
        }

        public void ChangeShowStatus(long infoID, Info_ShowStatus newStatus)
        {
            //
            Info_Data info = null;
            using (SAD_Modles ctx = new SAD_Modles())
            {
                info = ctx.Info_Datas.FirstOrDefault<Info_Data>(it => it.ID == infoID);
                if (info == null)
                {
                    throw new Exception(string.Format("要修改状态的信息[id:{0}]不存在", infoID));
                }

                if (info.ShowStatus != (byte)newStatus)
                {
                    InfoStatusChangeNoitfy(info);
                }

                info.ShowStatus = (byte)newStatus;
                ctx.SaveChanges();
            }            
        }

        public void InfoStatusChangeNoitfy(Info_Data info)
        {
            try
            {
                ShowNode_Data showNode = ShowNodeManager.Instance.GetShowNodeData(info.ShowNodeID);
                IPushInfoReceiver infoReceiver = System.ServiceModel.ChannelFactory<IPushInfoReceiver>.CreateChannel(new System.ServiceModel.BasicHttpBinding(), new System.ServiceModel.EndpointAddress(string.Format("http://{0}/InfoReceiver", showNode.HostUri)));
                if (info.ShowStatus == (byte)Info_ShowStatus.Yes)
                {
                    infoReceiver.AddInfo(info);
                }
                else if (info.ShowStatus != (byte)Info_ShowStatus.No)
                {
                    infoReceiver.RemoveInfo(info.ID, info.InfoCategoryID);
                }
            }
            catch (Exception ex)
            { }
        }
    }
}